#!/usr/bin/env python
#-*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui
from e100_ui import Ui_e100Dialog
from add_contact_ui import Ui_RecvDlg

import urllib2
import urllib
import re
import random
import time

import os
import sys

SENDTO=''

#secure account and password
def jiami(password):
    passlist = map((lambda x: ord(str(x))), password)
    passlist2 = []
    for i in passlist:
        if int(i)< 100:
            i = int(i) + 888
        passlist2.append(i)
    securePassword = ''
    for j in passlist2:
        securePassword = securePassword + str(j)
    securePassword = hex(long(securePassword))[2:-1]
    return securePassword

def jiemi(securePassword):
    securePassword = int(securePassword, 16)
    #print securePassword
    passlist = []
    for i in range(0, len(str(securePassword)),3):
        x = 0; y = 3
        x = x + i; y = y + i
        word = str(securePassword)[x:y]
        #print word
        if int(word) >= 800:
            word = int(word)-888
        passlist.append(int(word))
    passlist2 = map((lambda x: chr(x)), passlist)
    password = ''
    for j in passlist2:
        password = password + str(j)
    return password

class E100(object):
    JSESSIONID=''

    def __init__(self):
        self.JSESSIONID=''
        self.headers= {}
        self.getVerifyCode(isLogin=False)

    def getVerifyCode(self,savePath='./verifycode.jpg', isLogin=True):
        url="http://www.gd.chinamobile.com/image?sds=%s"% random.random() #16 bit, but python has 17 bit.
        headers={ 
                  'Host':'www.gd.chinamobile.com',
                  'User-Agent':'Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8',
                  'Accept':'image/png,image/*;q=0.8,*/*;q=0.5',
                  'Accept-Language':'zh-cn,zh;q=0.5',
                  'Accept-Encoding':'gzip,deflate',
                  'Accept-Charset':'GB2312,utf-8;q=0.7,*;q=0.7',
                  'Keep-Alive':'300',
                  'Connection':'keep-alive',
                  'Referer':'https://www.gd.chinamobile.com/e100/index.jsp',
                  #'Cookie':'JSESSIONID=%s' % self.JSESSIONID,
                }
        if isLogin:
            headers['Cookie'] = 'JSESSIONID=%s' % self.JSESSIONID
        print "===============send...url...headers========="
        print "url:%s"% url
        print "headers:%s"% headers
        req=urllib2.Request(url=url, headers=headers)
        conn = urllib2.urlopen(req)
        header=str(conn.info())
        print "================rev===================="
        print header
        res = conn.read()
        fobj=open(savePath, 'wb')
        fobj.write(res)
        fobj.close()
        #self.JSESSIONID = header.getheader('Set-Cookie')
        if not isLogin:
            self.JSESSIONID = re.findall(r"Set-Cookie: JSESSIONID=(.*); Path=/",header,re.M)[0]
            print self.JSESSIONID
    
    def login(self, cellphone, passwd, verifyCode):

        url="http://www.gd.chinamobile.com/ServicesServlet/LOGIN"

        request_json="""{"operation":"login","isProtocol":true,"_dl100Mobile":"","_loginInfo":"{\\"_loginType\\":\\"2\\",\\"_logonName\\":\\"%s"""% cellphone +"""\\",\\"_password\\":\\"%s"""% passwd +"""\\",\\"_smsRND\\":\\"\\",\\"isProtocol\\":true,\\"_login_backurl\\":\\"/e100/index.jsp\\",\\"_channel\\":8,\\"_imageCode\\":\\"%s"""% verifyCode +"""\\"}"}"""

        data = urllib.urlencode([('_request_json','%s'% request_json),('_channel', '8')])
        #data = """_request_json=%257B%2522operation%2522%253A%2522login%2522%252C%2522isProtocol%2522%253Atrue%252C%2522_dl100Mobile%2522%253A%2522%2522%252C%2522_loginInfo%2522%253A%2522%257B%255C%2522_loginType%255C%2522%253A%255C%25222%255C%2522%252C%255C%2522_logonName%255C%2522%253A%255C%2522%s"""% cellphone+""" %255C%2522%252C%255C%2522_password%255C%2522%253A%255C%2522%s"""% passwd+"""%255C%2522%252C%255C%2522_smsRND%255C%2522%253A%255C%2522%255C%2522%252C%255C%2522isProtocol%255C%2522%253Atrue%252C%255C%2522_login_backurl%255C%2522%253A%255C%2522%252Fe100%252Findex.jsp%255C%2522%252C%255C%2522_channel%255C%2522%253A8%252C%255C%2522_imageCode%255C%2522%253A%255C%2522%s"""% verifyCode+"""%255C%2522%257D%2522%257D&_channel=8"""
        print data
        print len(data)
        
        headers={
                  'Host':'www.gd.chinamobile.com',
                  'User-Agent':'Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8',
                  'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                  'Accept-Language':'zh-cn,zh;q=0.5',
                  'Accept-Encoding':'gzip,deflate',
                  'Accept-Charset':'GB2312,utf-8;q=0.7,*;q=0.7',
                  'Keep-Alive':'300',
                  'Connection':'keep-alive',
                  'Referer':'https://www.gd.chinamobile.com/e100/index.jsp',
                  'Cookie':'JSESSIONID=%s' % self.JSESSIONID,
                  'Content-Type':'application/x-www-form-urlencoded',
                  #'Content-Length':'%s' % len(data),
                }
        print headers
        req = urllib2.Request(url=url, headers=headers, data=data)
        conn = urllib2.urlopen(req)
        head = conn.info()
        body = conn.read()
        print head
        print body
        sucess="""http://www.gd.chinamobile.com:80/e100/index.jsp"""
        res=body.find(sucess)
        print res
        if -1 != res:
            return True
        else:
            errorMsg=re.findall(r"_R_STR_MESSAGE=(.*)%26amp", body, re.M)[0]
            #errorMsg=errorMsg.decode('gb2312').encode('utf-8')
            print errorMsg
            return errorMsg
    
    def getRandomSMS(self):
        url="http://www.gd.chinamobile.com/login/sendSMSRND.jsp?_logonName=E100_USER&_r=%s"% random.random()
        data=''
        headers={
                  'Host':'www.gd.chinamobile.com',
                  'User-Agent':'Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8',
                  'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                  'Accept-Language':'zh-cn,zh;q=0.5',
                  'Accept-Encoding':'gzip,deflate',
                  'Accept-Charset':'GB2312,utf-8;q=0.7,*;q=0.7',
                  'Keep-Alive':'300',
                  'Connection':'keep-alive',
                  'Referer':'https://www.gd.chinamobile.com/e100/index.jsp',
                  'Cookie':'JSESSIONID=%s' % self.JSESSIONID,
                  'Pragma':'no-cache',
                  'Cache-Control':'no-cache',
                  'Content-Length':'%s' % len(data),
                }
        
        print headers
        req = urllib2.Request(url=url, headers=headers, data=data)
        conn = urllib2.urlopen(req)
        head = conn.info()
        body = conn.read()
        print head
        print body

    def sendSMS(self, to, msg, logoCode):
        timeStamp = getTimeStamp()
        sendTime = getSendTime()
        url="http://www.gd.chinamobile.com/e100/SMS/Send?timeStamp=%s"% timeStamp
        request_json="""{"operation":"SMS_SEND","smsMessage":"{\\"person\\":\\"%s"""% to +"""\\",\\"content\\":\\"%s"""% msg+"""\\",\\"type\\":\\"0\\",\\"time\\":\\"%s"""% sendTime+"""\\",\\"payment\\":\\"0\\",\\"logoCode\\":\\"%s"""% logoCode +"""\\"}"}"""

        data = urllib.quote(request_json)
        print data
        print len(data)
        
        headers={
                  'Host':'www.gd.chinamobile.com',
                  'User-Agent':'Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8',
                  'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                  'Accept-Language':'zh-cn,zh;q=0.5',
                  'Accept-Encoding':'gzip,deflate',
                  'Accept-Charset':'GB2312,utf-8;q=0.7,*;q=0.7',
                  'Keep-Alive':'300',
                  'Connection':'keep-alive',
                  'Referer':'https://www.gd.chinamobile.com/e100/index.jsp',
                  'Content-Length':'%s' % len(data),
                  'Content-Type':'text/plain; charset=UTF-8',
                  'Cookie':'userSrcUrlL=undefined; userSrcUrlR=undefined; JSESSIONID=%s' % self.JSESSIONID,
                  'Pragma':'no-cache',
                  'Cache-Control':'no-cache',
                }
       
        print headers

        self.headers=headers

        req = urllib2.Request(url=url, headers=headers, data=data)
        conn = urllib2.urlopen(req)
        head = conn.info()
        body = conn.read()
        print head
        print body
        return body
        
    def keepActive(self):
        timeStamp = getTimeStamp()
        sendTime = getSendTime()
        url='http://www.gd.chinamobile.com/e100/SMS/Send'
        
        date = urllib.urlencode({'timeStamp':'%s'% timeStamp})
        headers=self.headers
        del headers['Content-Length']
        req = urllib2.Request(url=url, headers=headers, data=data)
        conn = urllib2.urlopen(req)
        head = conn.info()
        body = conn.read()
        print head

    def logout(self):
        url='http://www.gd.chinamobile.com/Logout'
        headers=self.headers
        del headers['Content-Length']
        del headers['Pragma']
        del headers['Cache-Control']
        headers['Accept']='image/png,image/*;q=0.8,*/*;q=0.5'
        headers['Referer'] = url
        req = urllib2.Request(url=url, headers=headers)
        conn = urllib2.urlopen(req)
        head = conn.info()
        body = conn.read()
        print head
        print body
        
        
def getTimeStamp():
    timeStampFlt=time.time()
    timeStamp = str(timeStampFlt).replace('.','0')
    return timeStamp
def getSendTime():
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())[:17]+"00.000000"


class SAVECONTACT(QtGui.QDialog):
    def __init__(self, parent=None):
        super(SAVECONTACT, self).__init__(parent)

        self.cellphoneFile = os.path.expanduser('~/.e100/cellphones')
        self.name=''
        self.cellphone=''

        self.ui = Ui_RecvDlg()
        self.ui.setupUi(self)


        QtCore.QObject.connect(self.ui.pushButton_save, QtCore.SIGNAL("clicked()"), self.save)
        QtCore.QObject.connect(self.ui.pushButton_cancle, QtCore.SIGNAL("clicked()"), self.cancle)

    def save(self):
        self.name=self.ui.lineEdit_name.text().toUtf8().data()
        self.cellphone=str(self.ui.lineEdit_phone.text())
        if self.name=='':
            QtGui.QMessageBox.warning(None, u'错误', u'姓名不能为空', u'确定')
            return
        if self.cellphone=='':
            QtGui.QMessageBox.warning(None, u'错误', u'手机号码不能为空', u'确定')
            return
        content = self.name+'='+self.cellphone+os.linesep
        print content

        if not os.path.isdir(os.path.split(self.cellphoneFile)[0]):
            os.mkdir(os.path.split(self.cellphoneFile)[0])
            os.chmod(os.path.split(self.cellphoneFile)[0], 0700)
        fobjw = open(self.cellphoneFile, 'a', -1)
        fobjw.write(content)
        fobjw.close()
        os.chmod(self.cellphoneFile, 0600)
        QtGui.QMessageBox.information(None, u"成功", u"增加联系人成功", u"确定")
        self.accept()

    def closeEvent(self, event):
        self.accept()

    def cancle(self):
        self.accept()


class RECVDLG(QtGui.QDialog):
    def __init__(self,parent=None):

        self.all_info={}
        self.checkList=[]
        self.cellphoneFile = os.path.expanduser('~/.e100/cellphones')
        try:
            fobjr = open(self.cellphoneFile, 'r')
        except IOError:
            QtGui.QMessageBox.warning(None, u"注意", u"手机号码配置文件不存在!", u"确定")
            return

        super(RECVDLG, self).__init__(parent)
        self.setWindowTitle(u"选择接收号码")

        self.pushButton = QtGui.QPushButton(self)
        self.pushButton.setGeometry(QtCore.QRect(150, 230, 75, 25))
        self.pushButton.setObjectName("pushButton_ok")
        self.pushButton.setText(u"确定")

        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.setRecv)


        for line in fobjr.readlines():
            if line.replace(os.linesep,'') != '':
                self.all_info[line.split('=')[0]]=line.split('=')[1].replace(os.linesep,'')
        fobjr.close()
        print self.all_info
        for i in xrange(len(self.all_info)):
            #0 1 2 ...
            checkName='checkBox_%s'% i
            #print checkName
            checkName= QtGui.QCheckBox(self)
            checkName.setGeometry(QtCore.QRect(90, 50+20*i, 200, 20))
            checkName.setObjectName(self.all_info.keys()[i])
            checkName.setText("%s:%s"% (QtCore.QString.fromUtf8(self.all_info.keys()[i]), self.all_info.values()[i]))
            self.checkList.append(checkName)


    def setRecv(self):
        global SENDTO
        SENDTO=''
        for i in self.checkList:
            if i.isChecked():
                #print i.text().split(':')[1]
                SENDTO=SENDTO+i.text().split(':')[1]+';'
        self.accept()



class E100_UI(QtGui.QMainWindow):
    isLogin=False

    def __init__(self, parent=None):
        self.configFile = os.path.expanduser('~/.e100/config')
        QtGui.QWidget.__init__(self, parent)
        self.ui=Ui_e100Dialog()
        self.centerUi()
        self.ui.setupUi(self)

        self.ui.label_status.setText(u"欢迎使用e100发短信工具")
        self.readAccount()
        self.focusInput()
        
        self.ui.pushButton_send.setEnabled(False)
        self.ui.pushButton_getCode.setEnabled(False)
        
        QtCore.QObject.connect(self.ui.pushButton_login, QtCore.SIGNAL("clicked()"), self.inOut)
        QtCore.QObject.connect(self.ui.pushButton_send, QtCore.SIGNAL("clicked()"), self.send)
        QtCore.QObject.connect(self.ui.pushButton_getCode, QtCore.SIGNAL("clicked()"), self.refreshCode)
        QtCore.QObject.connect(self.ui.pushButton_recv, QtCore.SIGNAL("clicked()"), self.getRecv)
        QtCore.QObject.connect(self.ui.pushButton_close, QtCore.SIGNAL("clicked()"), self.close)
        QtCore.QObject.connect(self.ui.pushButton_save, QtCore.SIGNAL("clicked()"), self.add_contact)
        msg = str(self.ui.textEdit_MSG.toPlainText())

        self.e100=E100()
        self.refreshCode(pic='verifycode.jpg',isNew=False) 
        self.ui.pushButton_getCode.setEnabled(True)
        
        self.sendCellphone=''
        self.password=''

    def readAccount(self):
        if os.path.isfile(self.configFile):
            fobjr = open(self.configFile, 'r', -1)
            accountAndpassword = fobjr.readlines()
            fobjr.close()
            self.ui.lineEdit_sendCellphone.setText(jiemi(accountAndpassword[0].replace(os.linesep, '', 1)))
            self.ui.lineEdit_password.setText(jiemi(accountAndpassword[1].replace(os.linesep, '', 1)))
    def saveAccount(self):
        if not os.path.isdir(os.path.split(self.configFile)[0]):
            os.mkdir(os.path.split(self.configFile)[0])
            os.chmod(os.path.split(self.configFile)[0], 0700)
        fobjw = open(self.configFile, 'w', -1)
        fobjw.write(jiami(self.sendCellphone) + os.linesep)
        fobjw.write(jiami(self.password) + os.linesep)
        fobjw.close()
        os.chmod(self.configFile, 0600)

    def focusInput(self):
        if str(self.ui.lineEdit_sendCellphone.text())=='':
            self.ui.lineEdit_sendCellphone.setFocus(QtCore.Qt.MouseFocusReason)
            return
        if str(self.ui.lineEdit_password.text())=='':
            self.ui.lineEdit_password.setFocus(QtCore.Qt.MouseFocusReason)
            return
        if str(self.ui.lineEdit_code.text())=='':
            self.ui.lineEdit_code.setFocus(QtCore.Qt.MouseFocusReason)
            return


    def centerUi(self):
        screen = QtGui.QDesktopWidget().screenGeometry() #获取显示器分辨率
        size = self.geometry() #获得窗体大小
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
            
    def refreshCode(self, pic='verifycode.jpg', isNew=True): #isNew 是否需要重网上下载图片
        if isNew:
            self.e100.getVerifyCode()
        pixmap = QtGui.QPixmap(pic)
        icon = QtGui.QIcon(pixmap)
        self.ui.pushButton_getCode.setIcon(icon)

    def inOut(self):
        if self.isLogin:
            self.logout()
        else:
            self.login()

    def login(self):
        self.sendCellphone = str(self.ui.lineEdit_sendCellphone.text())
        self.password = str(self.ui.lineEdit_password.text())
        #print self.sendCellphone, self.password
        verifyCode = str(self.ui.lineEdit_code.text())
        ####QtGui.QMessageBox.information(None, sendCellphone, verifyCode, u"done")
        res = self.e100.login(self.sendCellphone,self.password,verifyCode)
        if res!=True:
            self.refreshCode()
            res=(urllib.unquote(res)).decode('gb2312')
            #print u"登录失败"
            #print res
            QtGui.QMessageBox.information(None, u"登录失败", res, u"确定")
            self.ui.label_status.setText(res)
            self.isLogin=False
            return False
        if res:
            self.ui.label_status.setText(u"登录成功，请在验证码处输入随机短信密码")
            self.e100.getRandomSMS()
            QtGui.QMessageBox.information(None, u"登录成功", u"登录成功，请输入随机短信", u"确定")
            if self.ui.checkBox_remember.isChecked():
                self.saveAccount()
            ###self.refreshCode(pic='suijiCode.jpg', isNew=False)
            self.ui.pushButton_getCode.setIcon(QtGui.QIcon(':/suijiCode.jpg'))
            self.ui.pushButton_getCode.setEnabled(False)
            self.ui.pushButton_send.setEnabled(True)
            self.ui.pushButton_login.setEnabled(False)
            self.ui.lineEdit_sendCellphone.setReadOnly(True)
            self.ui.lineEdit_password.setReadOnly(True)
            ##self.ui.pushButton_login.setText(u'注销')
            self.isLogin=True

    def send(self):
        verifyCode = str(self.ui.lineEdit_code.text())
        revCellphone = str(self.ui.lineEdit_revCellphone.text())
        msg = self.ui.textEdit_MSG.toPlainText().toUtf8().data()
        #print msg
        content=msg.replace('\\','\\\\\\\\').replace(os.linesep, ' ')# 不接受回车 urllib.quote将\只是编码为2个%5C,实际需要5个
        print content
        #QtGui.QMessageBox.information(None, u"haha", msg, u"done")
        res = self.e100.sendSMS(to=revCellphone, msg=content, logoCode=verifyCode)
        true=True
        false=False
        jsonRes=eval(res)
        #jsonRes=res.replace('true',True).replace('false', False)
        result = jsonRes['resultObject']['result']
        message = jsonRes['message']
        login_type = jsonRes['login_type']
        if isinstance(message, unicode):
            print "isUNICODE"
        else:
            print "from utf-8 to unicode"
            message=message.decode('utf-8')

        if result:
            resultCode = jsonRes['resultCode']
            #message = jsonRes['message']

            sms_over_date = jsonRes['resultObject']['sms_over_date']
            day_send_sms = jsonRes['resultObject']['day_send_sms']
            month_send_sms = jsonRes['resultObject']['month_send_sms']
            free_month_num = jsonRes['resultObject']['free_month_num']
            day_send_num = jsonRes['resultObject']['day_send_num']
        
            free_leva_count = jsonRes['resultObject']['free_leva_count']
        
            status="今天共发了%s条,每天限发%s条,本月剩余%s条;本服务到期为%s" % (day_send_sms,day_send_num,free_leva_count, sms_over_date)
            print status

            print "resultCode: %s" % resultCode
            #print "message: %s"% message
        
            #print "今天共发了%s条"% day_send_sms
            #print "每天限发%s条"% day_send_num
            #print "本月剩余%s条"% free_leva_count
            #print "本服务器到期为:%s"% sms_over_date
            
            if isinstance(status, unicode):
                pass
            else:
                status=status.decode('utf-8')
            self.ui.label_status.setText(status)
            
            QtGui.QMessageBox.information(None, u"发送情况", message, u"确定")
            self.refreshCode()
            self.ui.pushButton_getCode.setEnabled(True)
       
        else:
            if 2==login_type:
                QtGui.QMessageBox.information(None, u"发送情况", message, u"确定")
            else:
                QtGui.QMessageBox.information(None, u"发送情况", message, u"确定")
                self.refreshCode()
                self.ui.pushButton_getCode.setEnabled(True)

        self.ui.lineEdit_code.clear()
        

    def logout(self):
        self.e100.logout()
        self.ui.pushButton_send.setEnabled(False)
        #self.ui.pushButton_login.setEnabled(True)
        self.ui.lineEdit_sendCellphone.setReadOnly(False)
        self.ui.lineEdit_password.setReadOnly(False)
        self.ui.pushButton_login.setText(u'登录')
        self.isLogin=False
    def closeEvent(self,event):
        self.close()
        event.accept()

    def getRecv(self):
        getRecvDlg=RECVDLG()
        try:
            if getRecvDlg.exec_():
                print SENDTO
                self.ui.lineEdit_revCellphone.setText(SENDTO)
                self.ui.textEdit_MSG.setFocus(QtCore.Qt.MouseFocusReason)
        except RuntimeError:
            self.ui.lineEdit_revCellphone.setFocus(QtCore.Qt.MouseFocusReason)
    def add_contact(self):
        saveDlg=SAVECONTACT()
        if saveDlg.exec_():
            pass

        
    def close(self):
        os.remove('verifycode.jpg')
        sys.exit(0)
        
        
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    e100_ui = E100_UI()
    e100_ui.show()
    sys.exit(app.exec_())
        
